home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Online / Qpopper / pop_init.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-22  |  9.7 KB  |  377 lines

  1. /*
  2.  * Copyright (c) 1989 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  */
  6.  
  7. #ifndef lint
  8. static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n";
  9. static char SccsId[] = "@(#)@(#)pop_init.c    2.1  2.1 3/18/91";
  10. #endif /* not lint */
  11.  
  12. #include <errno.h>
  13. #include <stdio.h>
  14. #include <sys/types.h>
  15. #ifdef POPSCO
  16. # include <sys/netinet/in.h>
  17. #else
  18. # include <netinet/in.h>
  19. #endif
  20. #include <netdb.h>
  21. #include <arpa/inet.h>
  22. #include <sys/param.h>
  23.  
  24. #if defined(SOLARIS2) || defined(SYSV) || defined(AIX)
  25. #include    <string.h>
  26. #define bcopy(src,dest,len)    (void) (memcpy(dest,src,len))
  27. #define bzero(dest,len)      (void) (memset(dest, (char)NULL, len))
  28. #define bcmp(b1,b2,n)        memcmp(b1,b2,n)
  29. #ifndef index
  30. # define index(s,c)        strchr(s,c)
  31. #endif
  32. #ifndef rindex
  33. # define rindex(s,c)        strrchr(s,c)
  34. #endif
  35. #else
  36. #include <strings.h>
  37. #endif
  38.  
  39. #include "popper.h"
  40.  
  41. /* CNS Kerberos IV */
  42. #ifdef KERBEROS
  43. AUTH_DAT kdata;
  44. #endif
  45.  
  46. extern int      errno;
  47. /*
  48. #ifdef POPSCO
  49. extern struct state    _res;
  50. #endif
  51. */
  52.  
  53. #ifdef STRDUP
  54. #include <stddef.h>
  55. #include <stdlib.h>
  56.  
  57. char *
  58. strdup(str)
  59.         char *str;
  60. {
  61.     int len;
  62.     char *copy;
  63.  
  64.     len = strlen(str) + 1;
  65.     if (!(copy = malloc((u_int)len)))
  66.     return((char *)NULL);
  67.     bcopy(str, copy, len);
  68.     return(copy);
  69. }
  70. #endif
  71.  
  72. authenticate(p, addr)
  73.      POP     *p;
  74.      struct sockaddr_in *addr;
  75. {
  76.  
  77. #ifdef KERBEROS
  78.     Key_schedule schedule;
  79.     KTEXT_ST ticket;
  80.     char instance[INST_SZ];  
  81.     char version[9];
  82.     int auth;
  83.   
  84.     if (p->kerberos) {
  85.     strcpy(instance, "*");
  86.     auth = krb_recvauth(0L, 0, &ticket, KERBEROS_SERVICE, instance,
  87.                 addr, (struct sockaddr_in *) NULL,
  88.                 &kdata, "", schedule, version);
  89.     
  90.     if (auth != KSUCCESS) {
  91.         pop_msg(p, POP_FAILURE, "Kerberos authentication failure: %s", 
  92.             krb_err_txt[auth]);
  93.         pop_log(p, LOG_WARNING, "%s: (%s.%s@%s) %s", p->client, 
  94.             kdata.pname, kdata.pinst, kdata.prealm, krb_err_txt[auth]);
  95.  
  96.         return(POP_FAILURE);
  97.     }
  98.  
  99. # ifdef DEBUG
  100.     if (p->debug)
  101.         pop_log(p, POP_DEBUG, "%s.%s@%s (%s): ok", kdata.pname, 
  102.         kdata.pinst, kdata.prealm, inet_ntoa(addr->sin_addr));
  103. # endif /* DEBUG */
  104.  
  105.     strncpy(p->user, kdata.pname, sizeof(p->user));
  106.  
  107.     }
  108. #endif /* KERBEROS */
  109.  
  110.     return(POP_SUCCESS);
  111. }
  112.  
  113. /* 
  114.  *  init:   Start a Post Office Protocol session
  115.  */
  116.  
  117. pop_init(p, argcount, argmessage)
  118. POP     *       p;
  119. int             argcount;
  120. char    **      argmessage;
  121. {
  122.  
  123.     struct sockaddr_in      cs;                 /*  Communication parameters */
  124.     struct hostent      *   ch;                 /*  Client host information */
  125.     int                     errflag = 0;
  126.     int                     c;
  127.     int                     len;
  128.     extern char         *   optarg;
  129.     int                     options = 0;
  130.     int                     sp = 0;             /*  Socket pointer */
  131.     char                *   trace_file_name;
  132.     struct hostent    *   hp = NULL;
  133.  
  134.     /*  Initialize the POP parameter block */
  135.     bzero ((char *)p,(int)sizeof(POP));
  136.  
  137.     /*  Initialize maildrop status variables in the POP parameter block */
  138.     p->msgs_deleted = 0;
  139.     p->last_msg = 0;
  140.     p->bytes_deleted = 0;
  141.     p->drop_size = 0;
  142.     p->mmdf_separator = NULL;
  143.     p->bulldir = BULLDIR;
  144.     p->dirty = 0;
  145.     p->kerberos = 0;
  146. #ifdef SERVER_MODE
  147.     p->server_mode = 1;
  148. #else
  149.     p->server_mode = 0;
  150. #endif
  151.  
  152.     /*  Save my name in a global variable */
  153.     p->myname = argmessage[0];
  154.  
  155.     /*  Get the name of our host */
  156.     if ((p->myhost = (char *)malloc(MAXHOSTNAMELEN+1)) == NULL) {
  157.     perror("malloc");
  158.     exit(1);    
  159.     }
  160.     (void)gethostname(p->myhost,MAXHOSTNAMELEN);
  161.     if (hp = gethostbyname(p->myhost)) {
  162.     if (! index(hp->h_name, '.')) {        /* FQN not returned */
  163.         /*
  164.          * SVR4 resolver is stupid and returns h_name as whatever
  165.          * you gave gethostbyname.  Thus do a reverse lookup
  166.          * on the first address and hope for the best.
  167.          */
  168.         u_long x = *(u_long *)hp->h_addr_list[0];
  169.         if ((hp = gethostbyaddr((char *)&x, 4, AF_INET)) != NULL) {
  170.             (void) strncpy (p->myhost, hp->h_name, MAXHOSTNAMELEN);
  171.             p->myhost[MAXHOSTNAMELEN] = '\0';
  172.         }
  173.     }
  174.     else {
  175.         (void) strncpy (p->myhost, hp->h_name, MAXHOSTNAMELEN);
  176.         p->myhost[MAXHOSTNAMELEN] = '\0';
  177.     }
  178.     }
  179.  
  180.  
  181.     /*  Open the log file */
  182. #ifdef SYSLOG42
  183.     (void)openlog(p->myname,0);
  184. #else
  185.     (void)openlog(p->myname,POP_LOGOPTS,POP_FACILITY);
  186. #endif
  187.  
  188.     /*  Process command line arguments */
  189.     while ((c = getopt(argcount,argmessage,"dkst:T:b:")) != EOF)
  190.         switch (c) {
  191.  
  192.             /*  Debugging requested */
  193.             case 'd':
  194.                 p->debug++;
  195.                 options |= SO_DEBUG;
  196. #ifdef DEBUG
  197.         if (p->debug)
  198.             pop_log(p,POP_PRIORITY,"Debugging turned on");
  199. #endif
  200.                 break;
  201.  
  202. #ifdef KERBEROS
  203.         case 'k':
  204.         p->kerberos++;
  205.         break;
  206. #endif    /* KERBEROS */
  207.  
  208.             /* Stats requested */
  209.             case 's':
  210.                 p->stats++;
  211.                 break;
  212.  
  213.         /* Bulletins requested */
  214.             case 'b':
  215.                 p->bulldir = optarg;
  216.                 break;
  217.  
  218.             /*  Debugging trace file specified */
  219.             case 't':
  220.                 p->debug++;
  221.  
  222. #ifdef DEBUG
  223.         if (p->trace)
  224.             pop_log(p,POP_PRIORITY,
  225.             "Tracing session and debugging information in file \"%s\"",
  226.                 trace_file_name);
  227. #endif
  228.  
  229.                 if ((p->trace = fopen(optarg,"a+")) == NULL) {
  230.                     pop_log(p,POP_PRIORITY,
  231.                         "Unable to open trace file \"%s\", err = %d",
  232.                             optarg,errno);
  233.                     exit(1);
  234.         }
  235.                 trace_file_name = optarg;
  236.                 break;
  237.  
  238.         /*  Timeout value passed.  Default changed */
  239.         case 'T':
  240.         pop_timeout = atoi(optarg);
  241.         break;
  242.  
  243.             /*  Unknown option received */
  244.             default:
  245.                 errflag++;
  246.         }
  247.  
  248.     /*  Exit if bad options specified */
  249.     if (errflag) {
  250. #ifdef KERBEROS
  251.         (void)fprintf(stderr,"Usage: %s [-d] [-k] [-s] [-t trace-file] [-T timeout] [-b bulldir]\n",argmessage[0]);
  252. #else
  253.         (void)fprintf(stderr,"Usage: %s [-d] [-s] [-t trace-file] [-T timeout] [-b bulldir]\n",argmessage[0]);
  254. #endif
  255.         exit(1);
  256.     }
  257.  
  258.     /*  Get the address and socket of the client to whom I am speaking */
  259.     len = sizeof(cs);
  260.     if (getpeername(sp,(struct sockaddr *)&cs,&len) < 0){
  261.         pop_log(p,POP_PRIORITY,
  262.             "Unable to obtain socket and address of client, err = %d",errno);
  263.         exit(1);
  264.     }
  265.  
  266.     /*  Save the dotted decimal form of the client's IP address 
  267.         in the POP parameter block */
  268.     p->ipaddr = (char *)strdup(inet_ntoa(cs.sin_addr));
  269.  
  270.     /*  Save the client's port */
  271.     p->ipport = ntohs(cs.sin_port);
  272.  
  273.     /*  Get the canonical name of the host to whom I am speaking */
  274.     ch = gethostbyaddr((char *) &cs.sin_addr, sizeof(cs.sin_addr), AF_INET);
  275.     if (ch == NULL){
  276.         pop_log(p,POP_PRIORITY,
  277.             "(v%s) Unable to get canonical name of client, err = %d",
  278.         VERSION, errno);
  279.         p->client = p->ipaddr;
  280.     }
  281.     /*  Save the cannonical name of the client host in 
  282.         the POP parameter block */
  283.     else {
  284.  
  285. #ifndef BIND43
  286.         p->client = (char *)strdup(ch->h_name);
  287. #else
  288.  
  289. # ifndef SCOR5
  290. #       include <arpa/nameser.h>
  291. #       include <resolv.h>
  292. # endif
  293.  
  294.         /*  Distrust distant nameservers */
  295.  
  296. #if !(defined(BSD) && (BSD >= 199103)) && !defined(OSF1) && !defined(HPUX10)
  297. # if (!defined(__RES)) || (__RES < 19940415)
  298. #  ifdef SCOR5
  299.     extern struct __res_state    _res;
  300. #  else
  301.         extern struct state     _res;
  302. #  endif
  303. # endif
  304. #endif
  305.         struct hostent      *   ch_again;
  306.         char            *   *   addrp;
  307.     char            h_name[MAXHOSTNAMELEN + 1];
  308.  
  309.         /*  We already have a fully-qualified name */
  310. #ifdef RES_DEFNAMES
  311.         _res.options &= ~RES_DEFNAMES;
  312. #endif
  313.  
  314.     strncpy(h_name, ch->h_name, sizeof(h_name));
  315.  
  316.         /*  See if the name obtained for the client's IP 
  317.             address returns an address */
  318.         if ((ch_again = gethostbyname(h_name)) == NULL) {
  319.             pop_log(p,POP_PRIORITY,
  320.                 "Client at \"%s\" resolves to an unknown host name \"%s\"",
  321.                     p->ipaddr, h_name);
  322.             p->client = p->ipaddr;
  323.         }
  324.         else {
  325.             /*  Save the host name (the previous value was 
  326.                 destroyed by gethostbyname) */
  327.             p->client = (char *)strdup(ch_again->h_name);
  328.  
  329.             /*  Look for the client's IP address in the list returned 
  330.                 for its name */
  331.             for (addrp=ch_again->h_addr_list; *addrp; ++addrp)
  332.                 if (bcmp(*addrp,&(cs.sin_addr),sizeof(cs.sin_addr)) == 0) break;
  333.  
  334.             if (!*addrp) {
  335.                 pop_log (p,POP_PRIORITY,
  336.                     "Client address \"%s\" not listed for its host name \"%s\"",
  337.                         p->ipaddr,h_name);
  338.                 p->client = p->ipaddr;
  339.             }
  340.         }
  341.  
  342. #ifdef RES_DEFNAMES
  343.     /* 
  344.      *  Must restore nameserver options since code in crypt uses
  345.      *  gethostbyname call without fully qualified domain name!
  346.      */
  347.     _res.options |= RES_DEFNAMES;
  348. #endif
  349.  
  350. #endif /* BIND43 */
  351.     }
  352.  
  353.     /*  Create input file stream for TCP/IP communication */
  354.     if ((p->input = fdopen(sp,"r")) == NULL){
  355.         pop_log(p,POP_PRIORITY,
  356.             "Unable to open communication stream for input, err = %d",errno);
  357.         exit (1);
  358.     }
  359.  
  360.     /*  Create output file stream for TCP/IP communication */
  361.     if ((p->output = fdopen(sp,"w")) == NULL){
  362.         pop_log(p,POP_PRIORITY,
  363.             "Unable to open communication stream for output, err = %d",errno);
  364.         exit (1);
  365.     }
  366.  
  367. #ifdef DEBUG
  368.     if (p->debug)
  369.     pop_log(p,POP_PRIORITY,
  370.         "(v%s) Servicing request from \"%s\" at %s",
  371.         VERSION,p->client,p->ipaddr);
  372. #endif
  373.  
  374.     return(authenticate(p, &cs));
  375. }
  376.  
  377.